﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ThreeToWin
{
    public partial class In_Game : Form
    {
        const int ROW = 4,
            COLUMN = 4;
        private Turn[,] table = new Turn[ROW+1, COLUMN+1];
        public enum Turn
        {
            Black,
            White,
            Null
        }
        //public enum Clickable
        //{
        //    yes,
        //    no,
        //    whatever
        //}
        Turn turn=Turn.Null,AI=Turn.Null,reverse=Turn.Null;
        public In_Game()
        {
            MessageBox.Show("错误：游戏窗口被不正确地加载。请联系开发者报告错误。");
            Application.Exit();
        }
        public In_Game(Turn AI)
        {
            InitializeComponent();
            //this.statue = statue;
            this.AI = AI;
            if (AI == Turn.Black)
            {
                reverse = Turn.White;
            }
            else if(AI==Turn.White)
            {
                reverse = Turn.Black;
            }
        }

        private void In_Game_Load(object sender, EventArgs e)
        {
            Icon = Properties.Resources.Main_Icon;
            turn = Turn.Black;
            for(int i = 0; i <= ROW; i++)
            {
                for(int j = 0; j <= COLUMN; j++)
                {
                    table[i,j] = Turn.Null;
                }
            }
        }
        protected override void OnClosed(EventArgs e)
        {
            Application.Exit();
        }
        private void OnClick(object sender, EventArgs e)
        {
            PictureBox picture = sender as PictureBox;
            if (picture.Enabled == false)
            {
                MessageBox.Show("AI发生错误。请联系开发者。");
                Application.Exit();
            }
            int row = Table.GetRow(picture),
                column = Table.GetColumn(picture);
            if (turn == Turn.Black)
            {
                picture.Image = Properties.Resources.Black;
                Gameover(Judgement(row, column,turn));
                table[row, column] = turn;
                turn = Turn.White;
            }
            else
            {
                picture.Image = Properties.Resources.White;
                Gameover(Judgement(row, column,turn));
                table[row, column] = turn;
                turn = Turn.Black;
            }
            picture.Enabled = false;
            if (turn == AI)
            {
                AIgo();
            }
        }
        private Turn Judgement(int row,int column,Turn turn)
        {
            int count = 0,
                n_r = row,
                n_c = column,
                temp = 1;
            while (n_c > 0 && table[n_r, n_c-1] == turn)
            {
                temp++;
                if (temp == 3)
                {
                    count++;
                    break;
                }
                n_c--;
            }
            n_c = column;
            if (temp != 3)
            {
                while (n_c < COLUMN && table[n_r, n_c + 1] == turn)
                {
                    temp++;
                    if (temp == 3)
                    {
                        count++;
                        break;
                    }
                    n_c++;
                }
            }
            n_c = column;
            temp = 1;
            while (n_r > 0 && table[n_r-1, n_c] == turn)
            {
                temp++;
                if (temp == 3)
                {
                    count++;
                    break;
                }
                n_r--;
            }
            n_r = row;
            if (temp != 3)
            {
                while (n_r < ROW && table[n_r+1, n_c ] == turn)
                {
                    temp++;
                    if (temp == 3)
                    {
                        count++;
                        break;
                    }
                    n_r++;
                }
            }
            if (count >= 2)
            {
                return turn;
            }
            n_r = row;
            temp = 1;
            while (n_c > 0 && n_r>0&&table[n_r-1, n_c - 1] == turn)
            {
                temp++;
                if (temp == 3)
                {
                    count++;
                    break;
                }
                n_c--;
                n_r--;
            }
            n_c = column;
            n_r = row;
            if (temp != 3)
            {
                while (n_c < COLUMN && n_r<ROW&&table[n_r+1, n_c + 1] == turn)
                {
                    temp++;
                    if (temp == 3)
                    {
                        count++;
                        break;
                    }
                    n_c++;
                    n_r++;
                }
            }
            if (count >= 2)
            {
                return turn;
            }
            n_r = row;
            n_c = column;
            temp = 1;
            while (n_c > 0 && n_r < ROW && table[n_r + 1, n_c - 1] == turn)
            {
                temp++;
                if (temp == 3)
                {
                    count++;
                    break;
                }
                n_c--;
                n_r++;
            }
            n_c = column;
            n_r = row;
            if (temp != 3)
            {
                while (n_c < COLUMN && n_r >0 && table[n_r - 1, n_c + 1] == turn)
                {
                    temp++;
                    if (temp == 3)
                    {
                        count++;
                        break;
                    }
                    n_c++;
                    n_r--;
                }
            }
            if (count >= 2)
            {
                return turn;
            }
            if (count == 1)
            {
                if (turn == Turn.White)
                {
                    return Turn.Black;
                }
                if (turn == Turn.Black)
                {
                    return Turn.White;
                }
            }
            return Turn.Null;
        }

        private void In_Game_Shown(object sender, EventArgs e)
        {
            if (turn == AI)
            {
                AIgo();
            }
        }

        void Gameover(Turn hand)
        {
            if (hand == Turn.Null) return;
            string who;
            if (hand == Turn.Black)
            {
                who = "黑棋";
            }
            else
            {
                who = "白棋";
            }
            MessageBox.Show(who + "获胜");
            Application.Exit();
        }
        void AIgo()
        {
            ArrayList clickable = new ArrayList();
            int[] yes = null;
            for (int r = 0; r <= ROW; r++)
            {
                for (int c = 0; c <= COLUMN; c++)
                {
                    if (table[r, c] == Turn.Null)
                    {
                        Turn win = Judgement(r, c, turn);
                        if (win == turn)
                        {
                            PictureBox box = Table.GetControlFromPosition(c, r) as PictureBox;
                            OnClick(box, new EventArgs());
                            return;
                        }
                        else if (win == reverse)
                        {
                            continue;
                        }
                        win = Judgement(r, c, reverse);
                        if (win == reverse)
                        {
                            yes = new int[2] { r, c };
                        }
                        else
                        {
                            clickable.Add(new int[2] { r, c });
                        }
                    }
                }
            }
            if (yes!=null)
            {
                PictureBox box = Table.GetControlFromPosition(yes[1], yes[0]) as PictureBox;
                OnClick(box, new EventArgs());
                return;
            }
            else
            {
                Random random = new Random();
                int[] ran = clickable[random.Next(0, clickable.Count)] as int[];
                PictureBox box = Table.GetControlFromPosition(ran[1], ran[0]) as PictureBox;
                OnClick(box, new EventArgs());
                return;
            }
            //Gameover(reverse);
        }
    }
}
